package cn.ubeta.b2c.api;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.Display;
import android.view.WindowManager;

import cn.ubeta.b2c.BuildConfig;
import cn.ubeta.b2c.cart.CheckoutActivity;
import cn.ubeta.b2c.utils.AppConfig;
import cn.ubeta.b2c.utils.Constants;
import cn.ubeta.b2c.utils.Dlog;
import cn.ubeta.b2c.utils.Installation;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;

import static cn.ubeta.b2c.MainApplication.getContext;

/**
 * Created by denny on 16/9/18.
 */

public abstract class ApiBase<T> {

    public final static short APP_ID = 121;
    public final static String APP_NAME = "jdvr";
    public final static String CLIENT_TYPE = "android";

    private static int sScreenWidth;
    private static int sScreenHeight;
    private static String sSn;

    /**
     * 获取路径目录
     * @return
     */
    public abstract String getBasePath();

    /**
     * 创建retrofit
     * @return
     */
    public T create() {
        return create(null);
    }

    /**
     * 创建retrofit
     * @return
     */
    public T create(List<NameValuePair> params) {
        // 获取泛型class
        Type genType = getClass().getGenericSuperclass();
        Type[] types = ((ParameterizedType) genType).getActualTypeArguments();
        Class<T> clazz =  (Class)types[0];

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(chain -> appendParams(chain, params))
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(String.format("https://%s/%s/", Constants.SERVER_HOST, getBasePath()))
                .addConverterFactory(ResponseConverterFactory.create())
                .client(client)
                .build();
        return retrofit.create(clazz);
    }

    /**
     * 追加公共参数
     * @param chain
     * @return
     * @throws IOException
     */
    private Response appendParams(Interceptor.Chain chain, List<NameValuePair> params) throws IOException {
        Request oldRequest = chain.request();

        // 添加新的参数
        HttpUrl.Builder builder = oldRequest.url()
                .newBuilder()
                .scheme(oldRequest.url().scheme())
                .host(oldRequest.url().host())
                // clientType
                .addQueryParameter("clientType", CLIENT_TYPE)
                // osVersion
                .addQueryParameter("osVersion", Build.VERSION.RELEASE)
                // clientVersion
                .addQueryParameter("clientVersion", BuildConfig.VERSION_NAME)
                // screen
                .addQueryParameter("screen", getScreen())
                // uuid
                .addQueryParameter("uuid", getUuid())
                // appName
                .addQueryParameter("appName", APP_NAME)
                // networkType
                .addQueryParameter("networkType", getNetworkType())
                // TODO area 格式说明？？？
                .addQueryParameter("area", AppConfig.getArea())
                // guid
                .addQueryParameter("guid", Installation.id(getContext()))
                // appId
                .addQueryParameter("appId", String.valueOf(APP_ID))
                .addQueryParameter("v", "1.0"); // API 版本号

        /* TODO 已登陆
        WLoginHelperApp loginHelper = LoginHelper.getJdLoginHelper(getContext());
        if (loginHelper != null) {
            String pin = loginHelper.getPin();
            if (!TextUtils.isEmpty(pin))
                builder.addQueryParameter("pin", pin);
            String u4 = loginHelper.getU4();
            if (!TextUtils.isEmpty(u4))
                builder.addQueryParameter("u4p_token", u4);
        }
        */

        // 追加额外参数
        if (params != null) {
            for (NameValuePair pair : params) {
                builder.addQueryParameter(pair.getName(), pair.getValue());
            }
        }

        // 新的请求
        Request newRequest = oldRequest.newBuilder()
                .method(oldRequest.method(), oldRequest.body())
                .url(builder.build())
                .build();

        // 打印订单参数
        if (BuildConfig.DEBUG) {
            Dlog.e(builder.toString());
        }

        return chain.proceed(newRequest);
    }

    /**
     * 获取下单参数
     * @return
     */
    public static String getFreightParams() {
        return "https://vrgw.jd.com/gw/getFreight.do?v=1.0" + getOrderParams(false);
    }

    /**
     * 获取下单参数
     * @return
     */
    public static String getOrderParams() {
        return "https://vrgw.jd.com/gw/submitOrder.do?v=1.0" + getOrderParams(true);
    }

    private static String getOrderParams(boolean withInvoice) {
        StringBuilder sb = new StringBuilder();
        List<NameValuePair> list = CheckoutActivity.getOrderParams(withInvoice, null);
        // clientType
        list.add(new BasicNameValuePair("clientType", CLIENT_TYPE));
        // osVersion
        list.add(new BasicNameValuePair("osVersion", Build.VERSION.RELEASE));
        // clientVersion
        list.add(new BasicNameValuePair("clientVersion", BuildConfig.VERSION_NAME));
        // screen
        list.add(new BasicNameValuePair("screen", getScreen()));
        // uuid
        list.add(new BasicNameValuePair("uuid", getUuid()));
        // appName
        list.add(new BasicNameValuePair("appName", APP_NAME));
        // networkType
        list.add(new BasicNameValuePair("networkType", getNetworkType()));
        // TODO area 格式说明？？？
        list.add(new BasicNameValuePair("area", AppConfig.getArea()));
        // guid
        list.add(new BasicNameValuePair("guid", Installation.id(getContext())));
        // appId
        list.add(new BasicNameValuePair("appId", String.valueOf(APP_ID)));
        //list.add(new BasicNameValuePair("v", "1.0")); // API 版本号

        /* TODO 已登陆
        WLoginHelperApp loginHelper = LoginHelper.getJdLoginHelper(getContext());
        if (loginHelper != null) {
            String pin = loginHelper.getPin();
            if (!TextUtils.isEmpty(pin))
                list.add(new BasicNameValuePair("pin", pin));
            String u4 = loginHelper.getU4();
            if (!TextUtils.isEmpty(u4))
                list.add(new BasicNameValuePair("u4p_token", u4));
        }
        */

        if (list != null) {
            for (NameValuePair nv : list) {
                sb.append("&" + nv.getName() + "=" + nv.getValue());
            }
        }
        return sb.toString();
    }

    /**
     * 获取网络类型
     * @return
     */
    private static String getNetworkType() {
        String strNetworkType = "";

        NetworkInfo networkInfo = ((ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                strNetworkType = "WIFI";
            } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                String _strSubTypeName = networkInfo.getSubtypeName();
                // TD-SCDMA   networkType is 17
                int networkType = networkInfo.getSubtype();
                switch (networkType) {
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                    case TelephonyManager.NETWORK_TYPE_IDEN: //api<8 : replace by 11
                        strNetworkType = "2G";
                        break;
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_B: //api<9 : replace by 14
                    case TelephonyManager.NETWORK_TYPE_EHRPD:  //api<11 : replace by 12
                    case TelephonyManager.NETWORK_TYPE_HSPAP:  //api<13 : replace by 15
                        strNetworkType = "3G";
                        break;
                    case TelephonyManager.NETWORK_TYPE_LTE:    //api<11 : replace by 13
                        strNetworkType = "4G";
                        break;
                    default:
                        // http://baike.baidu.com/item/TD-SCDMA 中国移动 联通 电信 三种3G制式
                        if (_strSubTypeName.equalsIgnoreCase("TD-SCDMA") || _strSubTypeName.equalsIgnoreCase("WCDMA") || _strSubTypeName.equalsIgnoreCase("CDMA2000")) {
                            strNetworkType = "3G";
                        } else {
                            strNetworkType = _strSubTypeName;
                        }
                        break;
                }
            }
        }
        return strNetworkType;
    }

    /**
     * 获取设备号
     * @return
     */
    public static String getUuid() {
        if (TextUtils.isEmpty(sSn)) {
            if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
                TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
                sSn = telephonyManager.getDeviceId();
                if (TextUtils.isEmpty(sSn))
                    sSn = telephonyManager.getSimSerialNumber();
            }
        }
        return sSn;
    }

    /**
     * 获取屏幕信息
     * @return
     */
    public static String getScreen() {
        if (sScreenWidth == 0 || sScreenHeight == 0) {
            // 方法1 Android获得屏幕的宽和高
            WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            sScreenWidth = display.getWidth();
            sScreenHeight = display.getHeight();
        }
        return sScreenWidth + "x" + sScreenHeight;
    }
}
